/*
 * Copyright (c) 2006-2019, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-05-24                  the first version
 */

#include "stm32f1xx_hal.h"
#include <rthw.h>
#include <rtthread.h>

#define _SCB_BASE                (0xE000E010UL)
#define _SYSTICK_CTRL        ( * (rt_uint32_t * )(_SCB_BASE + 0x0))
#define _SYSTICK_LOAD        ( * (rt_uint32_t * )(_SCB_BASE + 0x4))
#define _SYSTICK_VAL        ( * (rt_uint32_t * )(_SCB_BASE + 0x8))
#define _SYSTICK_CALIB        ( * (rt_uint32_t * )(_SCB_BASE + 0xC))
#define _SYSTICK_PRI        ( * (rt_uint8_t * )0xE000ED23UL)

// Updates the variable SystemCoreClock and must be called
// whenever the core clock is changed during program execution
//更新变量SystemCoreClock，必须调用
//每当程序执行过程中核心时钟发生变化时
extern void SystemCoreClockUpdate(void);

// Holds the system core clock , which is the system clock
// frequency suppiled to the SysTick timer and the processor
// core clock
//保存系统核心时钟，即系统时钟
//SysTick定时器和处理器支持的频率
//核心时钟
extern uint32_t SystemCoreClock;

static uint32_t _SysTick_Config(rt_uint32_t ticks)
{
        if((ticks - 1) > 0xFFFFFF)
        {
                return 1;
        }
        
        _SYSTICK_LOAD = ticks - 1;
        NVIC_SetPriority(SysTick_IRQn , (1 << __NVIC_PRIO_BITS) - 1);
        _SYSTICK_PRI = 0xFF;
        _SYSTICK_VAL = 0;
        _SYSTICK_CTRL = 0x07;
        
        return 0;
}


#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
/*
 * Please modify RT_HEAP_SIZE if you enable RT_USING_HEAP
 * the RT_HEAP_SIZE max value = (sram size - ZI size), 1024 means 1024 bytes
 */
#define RT_HEAP_SIZE (15*1024)
static rt_uint8_t rt_heap[RT_HEAP_SIZE];

RT_WEAK void *rt_heap_begin_get(void)
{
    return rt_heap;
}

RT_WEAK void *rt_heap_end_get(void)
{
    return rt_heap + RT_HEAP_SIZE;
}
#endif

/* timer 定时器中断服务函数调用 rt_os_tick_callback */
void rt_os_tick_callback(void)
{
    rt_interrupt_enter();
    
    rt_tick_increase();

    rt_interrupt_leave();
}
/*coretex - m 架构使用 SysTick_Handler()*/
void SysTick_Handler(void)
{
        rt_os_tick_callback();
}



/**
 * This function will initial your board.
 */
void rt_hw_board_init(void)
{
    /* 
     * TODO 1: OS Tick Configuration
     * Enable the hardware timer and call the rt_os_tick_callback function
     * periodically with the frequency RT_TICK_PER_SECOND. 
     */
        /* OS Tick 频率设置 ，RT_TICK_PER_SECOND = 1000 表示 1ms 触发一次中断 */
        _SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);

    /* Call components board initial (use INIT_BOARD_EXPORT()) */
#ifdef RT_USING_COMPONENTS_INIT
    rt_components_board_init();
#endif

#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
    rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
#endif
}

#ifdef RT_USING_CONSOLE

static int uart_init(void)
{
#error "TODO 2: Enable the hardware uart and config baudrate."
    return 0;
}
INIT_BOARD_EXPORT(uart_init);

void rt_hw_console_output(const char *str)
{
#error "TODO 3: Output the string 'str' through the uart."
}

#endif

